#ifndef MAIN_H
#define MAIN_H

#include "qt/qmainwindow.h"
#include "QtGui/qapplication.h"
#include "QtGui/qtgui"
#include "Agora.h"
#include "Header.h"
#include "AdminEventManager.h"
#include "secondWindow.h"
#include "ChannelPropertiesWindow.h"
#include "connexionWindow.h"
#include "createChannelWindow.h"
#include "enterPasswordWindow.h"
#include <map>
#include <string>

using namespace AgoraClient;

class Main: public QMainWindow
{
	Q_OBJECT

	public:

		class myQTreeView : public QTreeView
		{
		public:
			myQTreeView(Main *w) : QTreeView(w), _parent(w)
			{
			}

			void				keyPressEvent(QKeyEvent * eventArg)
			{
				_parent->keyPressEvent(eventArg);
			}
			Main *_parent;
		};
		struct MessageDestination
		{
			MessageDestination(){};
			MessageDestination(AgoraCore::MsgTextType _type, unsigned int _id);
			AgoraCore::MsgTextType type;
			unsigned int id;
		};

		Main();
		bool				IsBanned(unsigned int userId);
		bool				IsBanned(unsigned int userId, unsigned int chanId);
		void				keyPressEvent(QKeyEvent * eventArg);
		void				keyReleaseEvent(QKeyEvent * eventArg);
		void				SetPushToTalk(bool value);
		void				SetVAD(bool value, unsigned short levelVoiceActivity, unsigned short timeNoCheckAfterDetection);
		void				SetPushToTalkKey(int value);
		void				SetPushToTalkKeyText(QString &value);
		void				SetConnected(bool value);
		bool				IsConnected();
		int					getAudioInKey();
		void				addMessageToMessageBox(std::string* title, std::string* message, std::string* colorTitle, std::string* colorMessage);
		static void			changeUserChannel(AdminEventManager::EventArg *e, void *data);
		static void			onUserBannedFromServerListReceived(AdminEventManager::EventArg *e, void *data);
		static void			onUserBannedListReceived(AdminEventManager::EventArg *e, void *data);
		static void			fillTree(AdminEventManager::EventArg *e, void *data);
		static void			addUsers(AdminEventManager::EventArg *e, void *data);
		static void			showError(AdminEventManager::EventArg *e, void *data);
		static void			onChannelCreated(AdminEventManager::EventArg *e, void *data);
		static void			onChannelDeleted(AdminEventManager::EventArg *e, void *data);
		static void			onUserDisconnection(AdminEventManager::EventArg *e, void *data);
		static void			onUserConnection(AdminEventManager::EventArg *e, void *data);
		static void			onUserKicked(AdminEventManager::EventArg *e, void *data);
		static void			onUserChannelRightReceived(AdminEventManager::EventArg *e, void *data);
		static void			onUserHostRightReceived(AdminEventManager::EventArg *e, void *data);
		static void			onChannelRightReceived(AdminEventManager::EventArg *e, void *data);
		static void			onHostRightReceived(AdminEventManager::EventArg *e, void *data);
		static void			onChannelEdited(AdminEventManager::EventArg *e, void *data);
		static void			onUserMessageReceived(AdminEventManager::EventArg *e, void *data);
		static void			onChannelMessageReceived(AdminEventManager::EventArg *e, void *data);
		static void			onAllChannelMessageReceived(AdminEventManager::EventArg *e, void *data);
		static void			onUserDeleted(AdminEventManager::EventArg *e, void *data);
		static void			onUserCreation(AdminEventManager::EventArg *e, void *data);
		static void			onUserKickedFromServer(AdminEventManager::EventArg *e, void *data);
		static void			onUserBanned(AdminEventManager::EventArg *e, void *data);
		static void			onUserUnbanned(AdminEventManager::EventArg *e, void *data);
		static void			onUserBannedFromServer(AdminEventManager::EventArg *e, void *data);
		static void			onUserUnannedFromServer(AdminEventManager::EventArg *e, void *data);
		static void			onUserMuteSoundChannel(AdminEventManager::EventArg *e, void *data);
		static void			onUserMuteTxtChannel(AdminEventManager::EventArg *e, void *data);
		static void			onUserUnmuteSoundChannel(AdminEventManager::EventArg *e, void *data);
		static void			onUserUnmuteTxtChannel(AdminEventManager::EventArg *e, void *data);
		void				MoveToSelectedChannelWithPass(unsigned int channelId, const std::string &Password);

	signals:
		void				editChannelSig(IChannel *channel);
		void				addChannelSig(unsigned int idParent, unsigned int id, std::string *name);
		void				removeUserSig(unsigned int id);
		void				addUserSig(unsigned int idParent, unsigned int id, std::string* name);
		void				removeChannelSig(unsigned int id);
		void				error(QString text);
		void				messageToMessageBox(std::string* title, std::string* message, std::string* colorTitle, std::string* colorMessage);
	public slots:
		void				editChannelGUI(IChannel *channel);
		void				addChannelGUI(unsigned int idParent, unsigned int id, std::string *name);
		void				removeUserGUI(unsigned int id);
		void				addUserGUI(unsigned int idParent, unsigned int id, std::string* name);
		void				removeChannelGUI(unsigned int id);
		void				sendMessage();
		void				updateBandwidth();
		void				showGeneralProperties();
		void				ShowTreeContextMenu(const QPoint& pnt);
		void				showErrorGUIThread(QString);
		void				MoveToSelectedChannel();
		void				OpenCreateChanWindow();
		void				OpenChannelPropertiesWindow();
		void				DeleteChannel();
		void				KickSelectedUser();
		void				KickSelectedUserFromServer();
		void				connectNetwork();
		Agora*				GetAgora();
		bool				IsAudioInStarted();
		void				SetAudioInStarted(bool val);
		bool				IsAudioOutStarted();
		void				SetAudioOutStarted(bool val);
		void				changeUserChannelInTreeView(int userId, int chanId, std::string userName);
		void				addMessageToMessageBoxGUIThread(std::string* title, std::string* message, std::string* colorTitle, std::string* colorMessage);

	private:
		friend class secondWindow;
		friend class CreateChannelWindow;
		friend class ChannelPropertiesWindow;
		
		std::map<unsigned int, QStandardItem*>	_mapIdChannel;
		std::map<QStandardItem*, unsigned int>	_mapChannelId;
		std::map<unsigned int, QStandardItem*>	_mapIdUser;
		std::map<QStandardItem*, unsigned int>	_mapUserId;
		std::map<unsigned int, IUser *> _mapIdIUser;
		std::map<unsigned int, IChannel *> _mapIdIChannel;

		std::map<unsigned int, IChannelRight*>			_channelRights;
		IHostRight*										_hostRight;
		std::map<unsigned int, std::map<unsigned int, IChannelRight*> >			_userChannelRights;
		std::map<unsigned int, IHostRight*>										_userHostRight;
		std::map<int, MessageDestination> _mapMessageDestination;
		std::map<unsigned int, std::list<unsigned int> >					_userChannelBanned;
		std::list<unsigned int>								_userServerBanned;

		bool				IsUserAddToMessageTarget(unsigned int id);
		void				addIUser(IUser *user);
		void				addIChannel(IChannel *channel);
		QStandardItem*		getSelectedItem();
		void				addChannel(unsigned int idParent, unsigned int id, std::string name);
		void				addUser(unsigned int idParent, unsigned int id, std::string name);
		void				addItem(QStandardItem* it, unsigned int idParent, unsigned int id);
		void				removeChannel(unsigned int id);
		void				createChannel(std::string name, std::string password, std::string motd, std::string desc, int parentChannelId);
		

		Agora*				_agora;
		bool				_isConnected;
		bool				_audioInStarted;
		bool				_audioOutStarted;
		int					_audioInKey;
		unsigned int		_qualityAudio;
		char				_encoderKey;
		FrequenceEnum		_freq;
		ALFormat			_format;
		QVBoxLayout			*layout;
		QPushButton			*button;
		QMenuBar			*menu;
		QMenu				*fileMenu;
		QAction				*actionFile1;
		QAction				*actionFile2;
		QMenu				*propertiesMenu;
		QAction				*actionProperties;
		QMenu				*aboutMenu;
		QAction				*actionAbout1;
		QAction				*actionAbout2;
		QPushButton			*buttonInfo;
		QTreeView			*vue;
		QStandardItemModel	*modele;
		QIcon				*iconChan;
		QIcon				*iconPeople;
		QLabel*				acquisition;
		QLabel*				reception;
		QTextEdit*		messageBox;
		secondWindow		*newWindow;
		ChannelPropertiesWindow		*channelPropertiesWindow;
		connexionWindow		*cnxWindow;
		CreateChannelWindow	*crtChannelWindow;
		EnterPasswordWindow	*enterPasswordWindow;
		bool				_pushToTalk;
		int					_pushtoTalkKey;
		QString				_pushtoTalkKeyText;
		QComboBox			*sendMessageTarget;
		QLineEdit			*message;
		int					_messageTargetId;
		QPushButton			*sendText;
};

#endif
